﻿
using Dal;
using Entity;
using Entity.DTO;
using IDal;
using System.Runtime.CompilerServices;
using System.Security.Principal;

namespace Bll
{
    /// <summary>
    /// 菜单业务逻辑层
    /// </summary>
    public class MenuInfoBll : IMenuInfoBll
    {
        IMenuInfoDal _menuInfoDal;
        IUserInfoDal _userInfoDal;
        IUserInfoRoleInfoDal _r_UserInfo_RoleInfoDal;
        IRoleInfoMenuInfoDal _r_RoleInfo_MenuInfoDal;


        public MenuInfoBll(IMenuInfoDal menuInfoDal, IUserInfoDal userInfoDal, IUserInfoRoleInfoDal r_UserInfo_RoleInfoDal, IRoleInfoMenuInfoDal r_RoleInfo_MenuInfo)
        {
            _menuInfoDal = menuInfoDal;
            _userInfoDal = userInfoDal;
            _r_UserInfo_RoleInfoDal = r_UserInfo_RoleInfoDal;
            _r_RoleInfo_MenuInfoDal = r_RoleInfo_MenuInfo;
        }


        /// <summary>
        /// 创建菜单
        /// </summary>
        /// <returns></returns>
        public bool CreateMenuInfo(string title, string description, int level, int sort, string href, string icon, string target, string parentId, out string msg)
        {
            MenuInfo menuInfo = _menuInfoDal.GetDbSet()
                .Where(d => d.Title == title).FirstOrDefault();

            if (menuInfo != null)
            {
                msg = "菜单已经存在";
                return false;
            }

            MenuInfo entity = new MenuInfo();
            //创建guid 赋值给菜单id，目的是保证id唯一
            entity.Id = Guid.NewGuid().ToString();
            entity.Description = description;
            entity.Title = title;
            entity.Level = level;
            entity.Sort = sort;
            entity.Href = href;
            entity.Icon = icon;
            entity.Target = target;
            entity.ParentId = parentId;
            entity.CreateTime = DateTime.Now;

            //调用数据访问层创建菜单
            bool isSuccess = _menuInfoDal.CreateEntity(entity);

            if (isSuccess)
            {
                msg = "成功";
            }
            else
            {
                msg = "失败";
            }
            return isSuccess;
        }


        /// <summary>
        /// 软删除菜单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteMenuInfo(string id)
        {
            MenuInfo menuInfo = _menuInfoDal.GetDbSet().FirstOrDefault(u => u.Id == id);
            if (menuInfo == null)
            {
                return false;
            }

            menuInfo.IsDelete = true;

            return _menuInfoDal.UpdateEntity(menuInfo);
        }

        /// <summary>
        /// 批量软删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public bool DeleteMenuInfos(List<string> ids)
        {
            foreach (var id in ids)
            {
                MenuInfo menuInfo = _menuInfoDal.GetDbSet().FirstOrDefault(u => u.Id == id);
                if (menuInfo == null)
                {
                    return false;
                }

                menuInfo.IsDelete = true;

                _menuInfoDal.UpdateEntity(menuInfo);
            }

            return true;
        }


        /// <summary>
        /// 根据菜单id获取菜单信息
        /// </summary>
        /// <param name="menuId"></param>
        /// <returns></returns>
        public MenuInfo GetMenuInfoById(string menuId)
        {
            return _menuInfoDal.GetDbSet().Where(u => u.Id == menuId).FirstOrDefault();
        }


        /// <summary>
        /// 获取菜单集合
        /// </summary>
        public object GetMenuInfoList(string menuName, int page, int limit, out int count)
        {

            //左连接
            var queryable = from m1 in _menuInfoDal.GetDbSet().Where(d => !d.IsDelete)  //菜单
                            join m2 in _menuInfoDal.GetDbSet().Where(d => !d.IsDelete)  //菜单
                            on m1.ParentId equals m2.Id
                            into temp
                            from m3 in temp.DefaultIfEmpty()
                            select new
                            {
                                m1.Id,
                                m1.Title,
                                m1.Description,
                                m1.CreateTime,
                                m1.Href,
                                m1.Icon,
                                m1.Target,
                                parentTitle = m3.Title,
                                m1.Sort,
                                m1.Level
                            };


            //IQueryable<MenuInfo> queryable = _menuInfoDal.GetMenuInfosDbSet().Where(u => !u.IsDelete).OrderByDescending(d => d.CreateTime);

            if (!string.IsNullOrEmpty(menuName))
            {
                queryable = queryable.Where(u => u.Title.Contains(menuName));
            }


            //查询总条数
            count = queryable.Count();

            var list = queryable.OrderBy(d => d.Sort).Skip((page - 1) * limit).Take(limit).ToList().Select(d => new
            {
                d.Id,
                d.Title,
                d.Description,
                CreateTime = d.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                d.Href,
                d.Icon,
                d.Target,
                d.parentTitle,
                d.Sort,
                d.Level
            }).ToList();

            return list;
        }

        /// <summary>
        /// 获取下拉选备选数据
        /// </summary>
        public object GetSelectOptionList(string menuId)
        {
            //添加部门的时候不需要排除孩子的那些选项
            if (string.IsNullOrEmpty(menuId))
            {
                return _menuInfoDal.GetDbSet()
                .Where(d => d.Id != menuId && !d.IsDelete)
                .Select(d => new
                {
                    d.Id,
                    d.Title
                }).ToList();
            }

            //所有部门id集合                                                                                 
            List<ChidrenModel> allDepartmentIdInfos = _menuInfoDal.GetDbSet()
                .Where(d => d.IsDelete == false)
                .Select(d => new ChidrenModel
                {
                    Id = d.Id,
                    ParentId = d.ParentId
                }).ToList();

            //要排除掉的部门id集合
            List<string> excludeSonIds = new List<string>() { menuId };

            //获取下拉选的时候，排除掉自己的那个选项，还要排除自己的所有子集

            //找自己部门当前的儿子
            var sonIdInfos = allDepartmentIdInfos.Where(d => d.ParentId == menuId).ToList();
            if (sonIdInfos != null && sonIdInfos.Count() > 0)
            {
                //只拿出部门id放到集合中
                List<string> sonIds = sonIdInfos.Select(d => d.Id).ToList();
                excludeSonIds.AddRange(sonIds);

                //循环找儿子的儿子
                //foreach (var sonId in sonIds)
                //{
                //    var sunIds = allDepartmentIds.Where(id => id == sonId);
                //    if (sunIds != null && sunIds.Count() > 0)
                //    {
                //        excludeSonIds.AddRange(sunIds);
                //    }
                //}

                //调用找孩子的方法
                FindChidrenMenuId(allDepartmentIdInfos, sonIds, excludeSonIds);
            }

            // && !sonIds.Contains(d.Id)    not in ()
            //查询排除后的部门下拉选信息
            return _menuInfoDal.GetDbSet()
                .Where(d => d.Id != menuId && !excludeSonIds.Contains(d.Id) && !d.IsDelete)
                .Select(d => new
                {
                    d.Id,
                    d.Title
                }).ToList();
        }

        /// <summary>
        /// 递归找孩子菜单
        /// </summary>
        /// <param name="allMenuIds"></param>
        /// <param name="fatherIds"></param>
        /// <param name="excludeSonIds"></param>
        public void FindChidrenMenuId(List<ChidrenModel> allMenuIds, List<string> fatherIds, List<string> excludeSonIds)
        {
            //循环找儿子的儿子
            foreach (var fatherId in fatherIds)
            {
                var sonInfos = allMenuIds.Where(d => d.ParentId == fatherId).ToList();

                if (sonInfos != null && sonInfos.Count() > 0)
                {
                    List<string> sonIds = sonInfos.Select(d => d.Id).ToList();
                    excludeSonIds.AddRange(sonIds);

                    //递归找孩子
                    FindChidrenMenuId(allMenuIds, sonIds, excludeSonIds);
                }
            }
        }

        /// <summary>
        /// 更新菜单
        /// </summary>
        /// <returns></returns>
        public bool UpdateMenuInfo(string menuId, string title, string description, int level, int sort, string href, string icon, string target, string parentId, out string msg)
        {
            //根据账号找出菜单的信息
            MenuInfo entity = _menuInfoDal.GetDbSet().FirstOrDefault(u => u.Id == menuId);
            if (entity == null)
            {
                msg = "未找到菜单信息";
                return false;
            }

            //查询是否修改到其他的名字一样的情况
            MenuInfo otherEntity = _menuInfoDal.GetDbSet().FirstOrDefault(u => u.Id != menuId && u.Title == title);
            if (otherEntity != null)
            {
                msg = "此菜单名字已存在";
                return false;
            }

            entity.Title = title;
            entity.Description = description;
            entity.Level = level;
            entity.Sort = sort;
            entity.Href = href;
            entity.Icon = icon;
            entity.Target = target;
            entity.ParentId = parentId;

            //调用数据访问层
            bool isSucess = _menuInfoDal.UpdateEntity(entity);
            msg = "成功";
            return isSucess;
        }

        /// <summary>
        /// 获取首页菜单
        /// </summary>
        /// <returns></returns>
        public List<HomeMenuInfoModel> GetHomeMenu(string userId)
        {
            UserInfo userInfo = _userInfoDal.GetUserInfosDbSet().FirstOrDefault(u => u.Id == userId);
            if (userInfo == null)
            {
                return new List<HomeMenuInfoModel>();
            }

            List<HomeMenuInfoModel> allMenu;

            //是超级管理员
            if (userInfo.IsAdmin)
            {
                //先查询出所有的菜单信息
                allMenu = _menuInfoDal.GetDbSet().Where(m => !m.IsDelete).Select(m => new HomeMenuInfoModel
                {
                    Title = m.Title,
                    Target = m.Target,
                    Href = m.Href,
                    Icon = m.Icon,
                    Level = m.Level,
                    ParentId = m.ParentId,
                    Id = m.Id,
                    Sort = m.Sort
                }).ToList();
            }
            else
            {
                //查询当前用户可以查看的菜单有哪些
                List<string> menuIds = (from ur in _r_UserInfo_RoleInfoDal.GetDbSet().Where(u => u.UserId == userId)
                                        join rm in _r_RoleInfo_MenuInfoDal.GetDbSet()
                                        on ur.RoleId equals rm.RoleId
                                        select rm.MenuId).ToList();


                //先查询出所有的菜单信息
                allMenu = _menuInfoDal.GetDbSet().Where(m => menuIds.Contains(m.Id) && !m.IsDelete).Select(m => new HomeMenuInfoModel
                {
                    Title = m.Title,
                    Target = m.Target,
                    Href = m.Href,
                    Icon = m.Icon,
                    Level = m.Level,
                    ParentId = m.ParentId,
                    Id = m.Id,
                    Sort = m.Sort
                }).ToList();
            }



            //错的
            //var allMenu = (from ur in _r_UserInfo_RoleInfoDal.GetDbSet<R_UserInfo_RoleInfo>().Where(u => u.UserId == userId) //用户角色
            //               join rm in _r_RoleInfo_MenuInfoDal.GetDbSet<R_RoleInfo_MenuInfo>()  //角色菜单
            //               on ur.RoleId equals rm.RoleId
            //               join m in _menuInfoDal.GetDbSet<MenuInfo>() //菜单
            //               on rm.MenuId equals m.Id
            //               select new HomeMenuInfoModel
            //               {
            //                   Title = m.Title,
            //                   Target = m.Target,
            //                   Href = m.Href,
            //                   Icon = m.Icon,
            //                   Level = m.Level,
            //                   ParentId = m.ParentId,
            //                   Id = m.Id,
            //                   Sort = m.Sort
            //               }).ToList();

            //先找到最外层菜单
            var parentMenuList = allMenu.Where(m => m.Level == 1).OrderBy(m => m.Sort).ToList();

            //递归找孩子
            FindMenuChildren(parentMenuList, allMenu);

            ////给最外面那一层菜单找孩子
            //foreach (var parentMenu in parentMenuList)
            //{
            //    var childMenus = allMenu.Where(m => m.ParentId == parentMenu.Id && m.Level == 2).ToList();
            //    if (childMenus != null && childMenus.Count > 0)
            //    {
            //        parentMenu.Child = childMenus;

            //        //给childMenus孩子
            //        foreach (var childMenu in childMenus)
            //        {
            //            var childMenus2 = allMenu.Where(m => m.ParentId == childMenu.Id && m.Level == 3).ToList();
            //            if (childMenus2 != null && childMenus2.Count > 0)
            //            {
            //                childMenu.Child = childMenus2;
            //            }
            //        }
            //    }
            //}




            ////最外层的父类菜单model集合
            //List<HomeMenuInfoModel> parentModel = parentMenuList.Select(m => new HomeMenuInfoModel()
            //{
            //    Href = m.Href,
            //    Title = m.Title,
            //    Icon = m.Icon,
            //    Target = m.Target
            //}).ToList();

            //for (int i = 0; i < parentMenuList.Count(); i++)
            //{
            //    var childMenus = allMenu.Where(m => m.ParentId == parentMenuList[i].Id)
            //        .Select(m => new HomeMenuInfoModel()
            //        {
            //            Href = m.Href,
            //            Title = m.Title,
            //            Icon = m.Icon,
            //            Target = m.Target
            //        }).ToList();
            //    if (childMenus != null && childMenus.Count > 0)
            //    {
            //        parentModel[i].Child = childMenus;
            //    }
            //}



            return parentMenuList;
        }

        /// <summary>
        /// 递归找菜单孩子
        /// </summary>
        /// <param name="parentMenuList"></param>
        /// <param name="allMenu"></param>
        public void FindMenuChildren(List<HomeMenuInfoModel> parentMenuList, List<HomeMenuInfoModel> allMenu)
        {
            //给最外面那一层菜单找孩子
            foreach (var parentMenu in parentMenuList)
            {
                var childMenus = allMenu.Where(m => m.ParentId == parentMenu.Id && m.Level == parentMenu.Level + 1)
                    .OrderBy(m => m.Sort).ToList();
                if (childMenus != null && childMenus.Count > 0)
                {
                    parentMenu.Child = childMenus;

                    FindMenuChildren(childMenus, allMenu);
                }
            }
        }


        ///// <summary>
        ///// 为菜单解除绑定用户
        ///// </summary>
        ///// <param name="menuId"></param>
        ///// <param name="userIds"></param>
        ///// <returns></returns>
        //public bool UnbindUserInfo(string menuId, List<string> userIds)
        //{
        //    foreach (var userId in userIds)
        //    {
        //        //查询出当前菜单下绑定用户信息（中间表）
        //        var entity = _r_UserInfo_MenuInfoDal.GetDbSet<R_UserInfo_MenuInfo>().FirstOrDefault(r => r.UserId == userId && r.MenuId == menuId);
        //        if (entity != null)
        //        {
        //            //解绑其实就是删除中间表的数据
        //            //_r_UserInfo_MenuInfoDal.DeleteEntity(entity);

        //            _r_UserInfo_MenuInfoDal.DeleteEntity(entity.Id);
        //        }
        //    }

        //    //var entities = _r_UserInfo_MenuInfoDal.GetDbSet<R_UserInfo_MenuInfo>().Where(r => userIds.Contains(r.UserId) && r.MenuId == menuId).ToList();
        //    //_r_UserInfo_MenuInfoDal.BatchDeleteEntity(entities);

        //    return true;
        //}
    }
}